<template>
    <div class="h100 oh rel" ref="map" id="client-map">
        <the-tool
            v-if="cesiumMap"
            :cesium-map="cesiumMap"
            :recive-id="reciveId"
            :pick-layers.sync="pickLayers"
        />
        <the-func v-if="cesiumMap" :cesium-map="cesiumMap" />
        <the-select v-if="cesiumMap" v-model="pickLayers" />
    </div>
</template>

<script>
import { initViewer } from "@/public/lib/map";
import { Cesium, AppGlobalConfig, wutu3d } from "@/public/global/const";
import { FetchMonitorPointList, FetchWarningManageById } from "@/api";
import TheTool from "./component/TheTool";
import { staticComputer } from "@/public/util/vue";
import { WarnLevelMap, WarnTypeMap } from "@/public/global/map";
import DataCollection from "@/public/class/DataCollection";
import TheFunc from "./component/TheFunc";
import TheSelect from "./component/TheSelect";
import isNil from "ramda/src/isNil";
import DivPint from "./component/DivPint";
import Vue from "vue";

const LocalStorageKey = "com.map.fly";

function getTableHtml(data) {
    const ht = data
        .map((d) => {
            return `<tr><td width="140px">${d.key}</td><td width="240px">${d.value ||
                "-"}</td></tr>`;
        })
        .join("");
    return `<table class="info-table">${ht}</table>`;
}

export default {
    name: "TheCesiumMap",
    components: {
        TheFunc,
        TheTool,
        TheSelect,
    },
    props: {
        reciveId: {
            type: Number,
        },
        currentPond: {
            type: Object,
            default() {
                return {};
            },
        },
    },
    data() {
        return {
            pickLayers: [],
        };
    },
    computed: {
        cesiumMap: staticComputer(),
        label: staticComputer(),
        aps: staticComputer(),
    },
    watch: {
        pickLayers: "$_handlerPickLayers",
    },
    mounted() {
        if (isNil(this.reciveId)) {
            return;
        }
        let config = null;
        let center = {
            y: this.currentPond.latitude,
            x: this.currentPond.longitude,
            z: 3000.0,
            heading: 0,
            pitch: -90,
            roll: 360,
        };
        try {
            config = JSON.parse(this.currentPond.config3D);
        } catch(e) {
            config = null;
        }
        if (config && config.viewpoint) {
            center = config.viewpoint;
        }
        const viewer = initViewer(this.$refs.map, false, {
            center: center,
        });
        viewer.scene.globe.depthTestAgainstTerrain = false;
        viewer.scene.terrainProvider = new Cesium.CesiumTerrainProvider({
            url: AppGlobalConfig.CesiumTerrainProvider,
        });
        viewer.scene.primitives.add(
            new Cesium.Cesium3DTileset({
                url: AppGlobalConfig.Cesium3DTileset,
                maximumScreenSpaceError: 32,
                maximumMemoryUsage: 2048,
            }),
        );

        this.alarmLabels = [];

        this.$_apManage(viewer);
        this.cesiumMap = {
            viewer: viewer,
            aps: this.aps,
            // alarms: this.alarmLabels,
            // monitors: this.monitors,
            // aps: this.aps,
            // labels: this.labels,
        };
        if (!localStorage.getItem(LocalStorageKey)) {
            this.cesiumMap.viewer.wutu.openFlyAnimation(() => {});
            localStorage.setItem(LocalStorageKey, "1");
        }
        window.cesiumMap = this.cesiumMap;
    },
    created() {
        window.closeDangerLabel = () => {
            if (this.label) {
                this.label.visible = false;
            }
        };
    },
    beforeDestroy() {
        if (this.timer) {
            clearInterval(this.timer);
            this.timer = null;
        }
    },
    methods: {
        async $_apManage(viewer) {
            this.aps = [];
            this.aps = new DataCollection({
                matcher: (obj, item) => {
                    return obj.id === item.id;
                },
                creater: (item) => {
                    const position = Cesium.Cartesian3.fromDegrees(
                        item.longitude,
                        item.latitude,
                        item.inith - 5 || 515,
                    );

                    const DivPintConstructor = Vue.extend(DivPint);
                    const divPintInstance = new DivPintConstructor({});
                    divPintInstance.info = item;
                    divPintInstance.$mount(document.createElement("div"));

                    const obj = new wutu3d.DivPoint(viewer, {
                        html: divPintInstance.$el,
                        anchor: [-16, 16],
                        visible: this.pickLayers.some((layer) => +layer === item.monitorTypeId),
                        position,
                    });
                    obj.monitorTypeId = item.monitorTypeId;
                    obj.id = item.id;
                    obj.divPintInstance = divPintInstance;
                    return obj;
                },
                editer: (obj, item) => {
                    obj.divPintInstance.info = item;
                },
                remover: (obj) => {
                    obj.divPintInstance.$destroy();
                    obj.destroy();
                    this.aps.remove(obj);
                },
            });
            await this.$_updateMonitorPointList();
            this.timer = setInterval(() => {
                this.$_updateMonitorPointList();
            }, 1000 * 60 * 2);
        },
        async $_updateMonitorPointList() {
            const data = await FetchMonitorPointList({ id: this.reciveId });
            this.aps.update(data);
        },
        async $_addDangerLabel(item, position) {
            const data = await FetchWarningManageById({ id: item.id });
            if (!data) {
                return;
            }
            this.$_addLabel(
                position,
                "设备预警",
                getTableHtml([
                    {
                        key: "测点ID",
                        value: data.monitorPointId,
                    },
                    {
                        key: "测点名称",
                        value: data.monitorPointName,
                    },
                    {
                        key: "设备名称",
                        value: data.sensorName,
                    },
                    {
                        key: "预警等级",
                        value: WarnLevelMap[data.warnLevel],
                    },
                    {
                        key: "预警类型",
                        value: WarnTypeMap[data.warnType],
                    },
                    {
                        key: "预警原因",
                        value: data.description.split(";").join(";\n"),
                    },
                ]),
                "alarmbg",
            );
        },
        $_addLabel(position, title, content, className) {
            const viewer = this.cesiumMap.viewer;
            if (!viewer || !title || !content || !position) return;
            if (this.label) {
                this.label.destroy();
            }
            this.label = new wutu3d.DivPoint(viewer, {
                html: `<div  class="divpoint2 ${className ||
                    ""}" style="display:none;width: 400px;height: 320px;">
                    <div class="title" style="top:10px;left:120px;">${title}</div>
                    <div class="title-close" onclick="closeDangerLabel()"></div>
                    <div class="content" style="width: 250px;left: 120px;top:50px;">${content}</div>
                  </div >`,
                anchor: [0, 140],
                position: position,
                // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(1000, 200000),//按视距距离显示
                // scaleByDistance: new Cesium.NearFarScalar(10000, 1.0, 100000, 0.1),
            });
            this.label.visible = true;
        },
        $_handlerPickLayers() {
            const aps = this.cesiumMap.aps.list;
            const len = aps.length;
            for (let i = 0; i < len; ++i) {
                const billboard = aps[i];
                billboard.visible = this.pickLayers.some(
                    (item) => +item === billboard.monitorTypeId,
                );
            }
        },
    },
};
</script>

<style lang="scss"></style>
